﻿using LWH;
using LWH.ByteProtocol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ByteProtocolCSharpDemo
{
    /// <summary>
    /// 使用ProtocolParser进行协议解析，主要作用是处理黏包分包
    /// </summary>
    class IndefiniteLengthProtocolFactory : AbstractProtocolFactory<CircularByteBuffer>
    {
        IndefiniteLengthProtocolParser mProtocolParser = new IndefiniteLengthProtocolParser();

        /// <summary>
        /// 解析帧头，这里提供了一个数据池CircularByteBuffer和对应的帧头解析方法，
        /// 可以使用其他数据池，自己控制数据的储存读取对比，只要返回true就会调用
        /// 下面的getProtocol进行协议的进一步解析
        /// </summary>
        /// <param name="dataQueue"></param>
        /// <returns></returns>
        protected override bool matchHeader(CircularByteBuffer dataQueue)
        {
            return ProtocolParseTool.matchHeader(dataQueue, mProtocolParser.HeaderProperty.getData());
        }

        /// <summary>
        /// 在帧头解析成功后，进一步对协议的解析，这里的例子中dataQueue第一个可读取byte就是
        /// 匹配的帧头
        /// </summary>
        /// <param name="dataQueue"></param>
        /// <returns></returns>
        protected override AbstractProtocol getProtocol(CircularByteBuffer dataQueue)
        {
            IndefiniteLengthProtocol protocol = null;

            //尝试获取长度，如果成功会将长度数据储存到mParseProtocol的缓存数组中
            if (mProtocolParser.ParseLengthProperty.tryGetData(dataQueue))
            {
                //如果成功获取长度，则将解析协议包装成解析属性，尝试获取，以为tryGetData中会
                //调用getLength，所以必需确保getLength有效
                ByteBufferParseProperty protocolParseProperty = new ByteBufferParseProperty(mProtocolParser);

                if (protocolParseProperty.tryGetData(dataQueue))
                {
                    protocol = new IndefiniteLengthProtocol(dataQueue.Dequeue(protocolParseProperty.getLength()));
                }
            }

            return protocol;
        }
    }
}
